import java.util.HashSet;

/**
 * Class representing an action, i.e. a step in a plan.
 */
public class Action {
	
    private String name;

    /** Set of preconditions of the action */
    private HashSet<Predicate> preconditions;
    
    /** Add list of the action */
    private HashSet<Predicate> addList;
    
    /** Delete list of the action */
    private HashSet<Predicate> deleteList;

    /** The time required to complete the action in minutes*/
    private int duration;
    
    /** Latest start time */
    private int startTime;

    /** Is parallizable */
    private boolean isParallelizable;

    /** 
     * Returns start time of an action
     * @return
     */
    public int getStartTime() {
        return startTime;
    }

    /**
     * Returns true if action is parallelizable
     * @return
     */
    public boolean isParallelizable() {
        return isParallelizable;
    }

    /**
     * Returns the duration of an action
     * @return
     */
    public int getDuration() {
        return duration;
    }
    
    /** Sets the duration of an action
     * @param duration
     */
    public void setDuration(int duration) {
        this.duration = duration;
    }

    /** Sets the start time of an action
     */
    public void setStartTime(int startTime) {
        this.startTime = startTime;
    }

    /**
     * Sets if action is parallelizable
     * @param PL
     */
    public void setParallelizable(boolean PL) {
        this.isParallelizable = PL;
    }

    /**
     * Constructor for the Action class
     * 
     * @param name Action name
     * @param preconditions Set of preconditions for the action
     * @param addList Set of positive literals in the effect of the action
     * @param deleteList Set of negative literals in the effect of the action
     */
    public Action(String name, HashSet<Predicate> preconditions,
                    HashSet<Predicate> addList, HashSet<Predicate> deleteList, boolean isParallelizable, int duration) {
            this.preconditions = preconditions;
            this.addList = addList;
            this.deleteList = deleteList;

            this.name = name;
            this.isParallelizable = isParallelizable;
            this.duration = duration;
    }

    /**
     * Constructor for the Action class
     * @param name
     * @param isParallelizable
     */
    public Action(String name, boolean isParallelizable, int duration) {
            preconditions = new HashSet<Predicate>();
            addList = new HashSet<Predicate>();
            deleteList = new HashSet<Predicate>();
            this.duration = duration;
            this.name = name;
            this.isParallelizable = isParallelizable;
    }

    /**
     * Constructor for the Action class
     * @param predicates
     */
    public void addPreconditions(Predicate ... predicates) {
            for (Predicate p : predicates) {
                    preconditions.add(p);
            }
    }

    /**
     * Returns the set of preconditions for the action
     */
    public HashSet<Predicate> getPreconditions() {
            return preconditions;
    }

    /**
     * Returns the set of positive literals in the effect of the action
     */
    public HashSet<Predicate> getAddList() {
            return addList;
    }

    /**
     * Returns the set of negative literals in the effect of the action
     */
    public HashSet<Predicate> getDeleteList() {
            return deleteList;
    }

    /**
     * Add an item to the action's add list 
     * @param p
     */
    public void addToAddList(Predicate p) {
            addList.add(p);
    }

    /**
     * Add an item to the action's delete list 
     * @param p
     */
    public void addToDeleteList(Predicate p) {
            deleteList.add(p);
    }

	/**
	 * Returns true if Predicate p is in the action's add-list,
	 * false if it is not.
	 * @param p
	 */
	public boolean isInAddList(Predicate p) {
		return addList.contains(p);
	}
	
	/**
	 * Returns a string representation of the action
	 */
	public String toString() {
		return name + "(" + duration + ")" + " ST=" + startTime + " "  + preconditions;
		}

	/**
	 * Returns the name of the action
	 * @return
	 */
	public String getName() {
		return name;
	} 

}
